package com.project.frame.system.controller;

import com.project.frame.common.annotation.LogIgnore;
import com.project.frame.common.model.BaseResp;
import com.project.frame.common.utils.DateUtils;
import com.project.frame.system.service.UploadService;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.imageio.ImageIO;
import javax.imageio.stream.MemoryCacheImageInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;
import java.util.*;

/**
 * @创建人 super_dev_001
 * @创建时间 2018-06-28
 */
@Controller
@RequestMapping("/upload/")
public class UploadController {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Autowired
	UploadService uploadService;

	@Value("${upload.qiniu.enable:false}")
	private boolean qiniuEnable;
	@Value("${upload.local.domain:}")
	private String dataServerDomain;
	@Value("${upload.image.dir:}")
	private String imageRootDir;
	@Value("${upload.image.size:1024000}")
	private Long imageMaxSize;
	// 文件允许格式
	private String[] allowFiles = { "swf", "wmv", "gif", "png", "jpg", "jpeg",
			"bmp" };

	String image = "/upload/img/";


	@RequestMapping(value = "/img/{image:[a-zA-Z0-9\\\\.]+}")
	@LogIgnore
	public void fetchImg(@PathVariable String image,HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		String userDir = System.getProperty("user.dir");
		File file = FileUtils.getFile(userDir,imageRootDir, image);
		FileInputStream fis = null;
		response.setContentType("image/gif");
		try {
			OutputStream out = response.getOutputStream();
			fis = new FileInputStream(file);
			byte[] b = new byte[fis.available()];
			fis.read(b);
			out.write(b);
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}


	@RequestMapping(value = "/img-upload", method = { RequestMethod.POST })
	@ResponseBody
	@LogIgnore
	public BaseResp imgUpload(@RequestParam("picFile") MultipartFile file) {
		BaseResp resp = new BaseResp();
		Map<String,Object> data = new HashMap<>();
		String fileName = "";
		resp.setData(data);
		if (file.isEmpty()) {
			resp.setMsg("未包含文件上传域");
		} else if (file.getSize() > imageMaxSize*20) {
			resp.setMsg("文件大小超出限制");
		} else {
			BufferedImage newImage = null;
			try {
				newImage=multipartFileToImage(file);
			} catch (IOException e) {
				e.printStackTrace();
			}

			String originalName = file.getOriginalFilename();
			originalName = originalName.toLowerCase();
			String userDir = System.getProperty("user.dir");

			if (FilenameUtils.isExtension(originalName, allowFiles)) {
				String type = FilenameUtils.getExtension(originalName);
				data.put("type",type);
				String id = DateUtils.format(new Date(),"yyyyMMddHHmmssSSS");
				fileName = id+"."+type ;
				data.put("fileName",fileName);
				File path = FileUtils.getFile(userDir,imageRootDir);
				try {
					FileUtils.forceMkdir(path);
					File ordinalFile = FileUtils.getFile(path,fileName);
					String url = "";
					if(qiniuEnable==true){
						file.transferTo(ordinalFile);
						url = uploadService.upload(ordinalFile, ordinalFile.getName());
					}else{
						ImageIO.write(newImage, type, ordinalFile);
						url = dataServerDomain+image + fileName;
					}

					resp.setUrl(url);
					resp.setSuccess(true);
					data.put("size",file.getSize());
					data.put("originalName",originalName);

				} catch (IOException e) {
					resp.setMsg("上传请求异常");
					logger.error(e.getMessage(), e);
				}
			} else {
				resp.setMsg("不允许的文件格式");
			}
		}
		return resp;
	}


	@RequestMapping(value = "/uploadImages", method = { RequestMethod.POST })
	@ResponseBody
	public BaseResp uploadImages(HttpServletRequest request)  throws Exception{
		BaseResp resp = new BaseResp();
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		MultiValueMap<String, MultipartFile> map = multipartRequest.getMultiFileMap();
		if (map != null) {
			Iterator iter = map.keySet().iterator();
			while (iter.hasNext()) {
				String str = (String) iter.next();
				List<MultipartFile> fileList = map.get(str);
				for (MultipartFile mpf : fileList) {
					Map<String,Object> obj = new HashMap<>();
					String originalName = mpf.getOriginalFilename();
					originalName = originalName.toLowerCase();
					if (FilenameUtils.isExtension(originalName, allowFiles)) {
						String type = FilenameUtils.getExtension(originalName);
						obj.put("type",type);
						String id = DateUtils.format(new Date(),"yyyyMMddHHmmssSSS");
						String fileName = id + "." + type;
						obj.put("fileName",fileName);
						File path = FileUtils.getFile(imageRootDir);
						try {
							BufferedImage newImage = null;
							try {
								newImage=getNewImage(mpf,700,700);
							} catch (IOException e) {
								e.printStackTrace();
							}

							FileUtils.forceMkdir(path);
							File ordinalFile = FileUtils.getFile(path,fileName);
							ImageIO.write(newImage, type, ordinalFile);
//							mpf.transferTo(ordinalFile);

							String url = dataServerDomain+image + fileName;
							resp.setUrl(url);
							obj.put("size",mpf.getSize());
							obj.put("originalName",originalName);

							//super_dev_001 2020/5/9
							obj.put("src",url);
							obj.put("title",originalName);

						} catch (IOException e) {
							obj.put("state","上传请求异常");
							logger.error(e.getMessage(), e);
						}
					} else {
						obj.put("state","不允许的文件格式");
					}
					resp.setData(obj);
				}
			}
		}
		return resp;
	}


	private BufferedImage getNewImage(MultipartFile oldImage, double width, double height) throws IOException{
		/*srcURl 原图地址；deskURL 缩略图地址；comBase 压缩基数；scale 压缩限制(宽/高)比例*/

		ByteArrayInputStream bais = new ByteArrayInputStream(oldImage.getBytes());
		MemoryCacheImageInputStream mciis = new MemoryCacheImageInputStream(bais);
		Image src = ImageIO.read(mciis);
		double srcHeight = src.getHeight(null);
		double srcWidth = src.getWidth(null);
		double deskHeight = 0;//缩略图高
		double deskWidth  = 0;//缩略图宽
		if (srcWidth>srcHeight) {

			if (srcWidth>width) {
				if (width/height>srcWidth/srcHeight) {
					deskHeight = height;
					deskWidth = srcWidth/(srcHeight/height);
				}
				else {
					deskHeight = width/(srcWidth/srcHeight);
					deskWidth = width;
				}
			}
			else {

				if (srcHeight>height) {
					deskHeight = height;
					deskWidth = srcWidth/(srcHeight/height);
				}else {
					deskHeight=srcHeight;
					deskWidth=srcWidth;
				}

			}

		}
		else if(srcHeight>srcWidth)
		{
			if (srcHeight>(height)) {
				if ((height)/width>srcHeight/srcWidth) {
					deskHeight = srcHeight/(srcWidth/width);
					deskWidth = width;
				}else {
					deskHeight = height;
					deskWidth = (height)/(srcHeight/srcWidth);
				}
			}
			else {
				if (srcWidth>width) {
					deskHeight = srcHeight/(srcWidth/width);
					deskWidth = width;
				}else {
					deskHeight=srcHeight;
					deskWidth=srcWidth;
				}

			}

		}
		else if (srcWidth==srcHeight) {

			if (width>=(height)&&srcHeight>(height)) {
				deskWidth=(height);
				deskHeight=(height);
			}
			else if (width<=(height)&&srcWidth>width) {
				deskWidth=width;
				deskHeight=width;
			}
			else  if (width==(height)&&srcWidth<width) {
				deskWidth=srcWidth;
				deskHeight=srcHeight;
			}
			else {
				deskHeight=srcHeight;
				deskWidth=srcWidth;
			}

		}
		BufferedImage tag = new BufferedImage((int)deskWidth,(int)deskHeight,
				BufferedImage.TYPE_3BYTE_BGR);
		tag.getGraphics().drawImage(src, 0, 0, (int)deskWidth, (int)deskHeight, null); //绘制缩小后的图
		return tag;
	}

	private BufferedImage multipartFileToImage(MultipartFile oldImage) throws IOException{
		ByteArrayInputStream bais = new ByteArrayInputStream(oldImage.getBytes());
		MemoryCacheImageInputStream mciis = new MemoryCacheImageInputStream(bais);
		Image src = ImageIO.read(mciis);
		double srcHeight = src.getHeight(null);
		double srcWidth = src.getWidth(null);
		BufferedImage tag = new BufferedImage((int)srcWidth,(int)srcHeight,
				BufferedImage.TYPE_3BYTE_BGR);
		tag.getGraphics().drawImage(src, 0, 0, (int)srcWidth, (int)srcHeight, null);
		return tag;
	}

}
